/**
 * This file is a part of qloudgen-sec. 
 * You can redistribute qloudgen-sec and/or modify it under the terms of the Lesser GNU General Public License version 3. 
 * qloudgen-sec is distributed WITHOUT ANY WARRANTY. 
 *
 * See the Lesser GNU General Public License for more details at http://www.gnu.org/licenses/. 
 **/
package org.qloudgen.sec.cas.client.proxy;

import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;

import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.qloudgen.sec.cache.Cache;
import org.qloudgen.sec.cas.client.CacheStorage;

/**
 * <p>Title: Cas Client Proxy Granting Ticket Storage Implementation</p>
 * <p>Description: Wrappered cas pgtiou and pgtid storage.</p>
 * <p>Copyright: qloudgen/sec 2014</p>
 * @author <a href="mailto:hyq.dd.sun@gmail.com">glue.3M</a>
 */
public final class CasProxyGrantingTicketStorage extends CacheStorage implements ProxyGrantingTicketStorage {
	/**
	 * Log output.
	 */
	private final static Logger logger = LoggerFactory.getLogger( CasProxyGrantingTicketStorage.class );
	/**
	 * Default callback pgtiou cache name.
	 */
	private static String DEFAULT_PGTIOU_CACHE = "CAS-PGTIOU";
	/**
	 * Default pgtiou timeout in milliseconds.
	 */
	private static long DEFAULT_PGTIOU_TIMEOUT = 60000;
	/**
	 * Cache timeout.
	 */
	private long cacheTimeout = 0L;	

	/**
	 * Default constructor.
	 */
	public CasProxyGrantingTicketStorage() {
		//
		super( DEFAULT_PGTIOU_CACHE , null );
		//
		this.cacheTimeout = DEFAULT_PGTIOU_TIMEOUT;
	}

	/**
	 * Returns current cache timeout.
	 *
	 * @return long
	 */
	public long getCacheTimeout() {
		return cacheTimeout;
	}
	
	/**
	 * Sets current cache timeout.
	 *
	 * @param cacheTimeout
	 */
	public void setCacheTimeout(long cacheTimeout) {
		this.cacheTimeout = cacheTimeout;
	}

	/**
	 * Returns current proxyGrantingTicket by proxyGrantingTicketIou.
	 *
	 * @param proxyGrantingTicketIou
	 * @return String
	 */
	public String retrieve(final String proxyGrantingTicketIou) {
		//
		Cache<String,CasProxyGrantingTicketHolder> cache = getCache();
		CasProxyGrantingTicketHolder holder = cache.get( proxyGrantingTicketIou );
		if ( holder == null ) {
			logger.debug( "Current pgt ticket not exist by pgt iou...[{}][{}]" , proxyGrantingTicketIou );
			return null;
		}
		//
		logger.debug( "Started retrieve pgt iou & ticket...[{}][{}]" , proxyGrantingTicketIou , holder.getProxyGrantingTicket() );
		//
		return holder.getProxyGrantingTicket();
	}

	/**
	 * Sets current proxyGrantingTicketIou and proxyGrantingTicket.
	 *
	 * @param proxyGrantingTicketIou
	 * @param proxyGrantingTicket
	 */
	public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) {
		//
		logger.debug( "Starting save pgt iou & ticket...[{}][{}]" , proxyGrantingTicketIou , proxyGrantingTicket );
		//
		getCache().put( proxyGrantingTicketIou , new CasProxyGrantingTicketHolder( proxyGrantingTicket ) );
	}

	/**
	 * This clean will depends current cache manager implementation.
	 */
	public void cleanUp() {
		//
		Cache<String,CasProxyGrantingTicketHolder> cache = getCache();
		for ( Map.Entry<String,CasProxyGrantingTicketHolder> holderEntry : cache.entrySet() ) {
			//
			if ( holderEntry.getValue().isExpired( cacheTimeout ) ) {
				String proxyGrantingTicketIou = holderEntry.getKey();
				String proxyGrantingTicket = holderEntry.getValue().getProxyGrantingTicket();
				//
			    cache.remove( holderEntry.getKey() );
				//
				logger.debug( "Started cleanup pgt iou & ticket...[{}][{}]" , proxyGrantingTicketIou , proxyGrantingTicket );
			}
		}
	}
	
	/**
	 * Returns the String representation.
	 *
	 * @return String
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append( "[" );
		builder.append( super.toString() );
		builder.append( "-->" );
		builder.append( "cacheTimeout=" ).append( cacheTimeout );
		builder.append( "]" );
		//
		return builder.toString();
	}
}